#!/usr/bin/perl
$\=$/;
use lib 'mods';
use db_config;
use ExploitFarm_SQL;
use Util::Logger;
use submitter;
require 'config.pl';

use Socket;

our $port=62674;
our $log_file='ef_server_log.txt';
our $sender_timeout=4;
our $serve_timeout=5*60;


$SIG{ALRM}=sub {$l->info("Timeout!\n"); exit(1);};

sub begin_log
{
    $l=new Util::Logger($log_file);
    die "Can`t open log file '$log_file' : $!" if (!defined $l);
    $l->info("Service start");
}


sub serve
{
    $_=<$c>;
    my ($exploit,$team)=split ' ';
    $l->info("Client $client_name with exploit '$exploit' team '$team'");
    
     $db=new ExploitFarm_SQL($db_host,$db_port,$db_name,$db_login,$db_pass);
     $db->connect();
     
    alarm($serve_timeout);
    while(<$c>)
    {
	alarm(0);
	s/[\r\n]+$//;
        $l->info(">GotS|$client_name|$exploit|$team|$_");
#	$flag_regex='^.*$';
	while(/($flag_regex)/gc)
	{
	    print "1: $1\n";
	    $l->info("|GotF|$client_name|$exploit|$team|$1");
	    $db->put_flags($exploit,$team,[$1]);
	}
	alarm($serve_timeout);
    }
    alarm(0);
}

sub accept_loop
{
    socket($s, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
    setsockopt($s, SOL_SOCKET, SO_REUSEADDR, 1);
    my $my_addr = sockaddr_in($port, INADDR_ANY);
    bind($s, $my_addr);
    listen($s, SOMAXCONN) or die "Couldn't listen on port $server_port : $!\n";
    $l->info("Socket on port $port created");
        
    while ($client=accept($c, $s))
    {
        my($port,$iaddr) = sockaddr_in($client);
	my $name = gethostbyaddr($iaddr,AF_INET);
	our $client_name=$name;
	our $client_port=$port;
				      
	($client,$port)=inet_aton($client);
        my $pid=fork();
        if ($pid>0) #parent
        {
	    #$SIG{INT}=\&stop_parent;
	    $SIG{CHLD}=IGNORE;
	    close $c;
	}elsif($pid==0) #child
        {
	    #$SIG{INT}=\&stop_child;
	    close $s;
	    serve();
	    shutdown($s,2);
	    exit(0);
	}else
	{
	    print "FORK ERROR!";
	}
    }									    
}

begin_log();
accept_loop();
